#include "udsclient.h"
#include "crccalculater.h"
#include "hexparser.h"
#include "qdir.h"
#include "qjsonobject.h"
#include "securityalgorithm.h"
#include "udstp.h"
#include "flashexecutor.h"
#include "QRandomGenerator"

UdsClient::UdsClient()
{
    pstUDSService = UDS_GetUDSServiceInfo(&SupSerItem);
}

void UdsClient::UdsServiceHandle()
{

}

/*dig session*/
static void UDS_DigSession(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg);

/*control DTC setting*/
static void UDS_ControlDTCSetting(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg);

/*communication control*/
static void UDS_CommunicationControl(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg);

/*security access*/
static void UDS_SecurityAccess(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg);

/*read data by identifier*/
static void UDS_ReadDataByIdentifier(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg);

/*write data by identifier*/
static void UDS_WriteDataByIdentifier(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg);

/*request download*/
static void UDS_RequestDownload(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg);

/*transfer data*/
static void UDS_TransferData(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg);

/*request transfer exit*/
static void UDS_RequestTransferExit(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg);

/*routine control*/
static void UDS_RoutineControl(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg);

/*reset ECU*/
static void UDS_ResetECU(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg);

// /*Tester present service*/
// static void UDS_TesterPresent(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg);

/***********************UDS service Static Global value************************/
/*dig serverice config table*/
tUDSService gs_astUDSService[] =
{
    /*diagnose mode control*/
    {
        0x10u,
        UDS_DigSession
    },

    /*communication control*/
    {
        0x28u,
        UDS_CommunicationControl
    },

    /*control DTC setting*/
    {
        0x85u,
        UDS_ControlDTCSetting
    },

    /*security access*/
    {
        0x27u,
        UDS_SecurityAccess
    },

    /*read data by identifier*/
    {
        0x22u,
        UDS_ReadDataByIdentifier
    },

    /*write data by identifier*/
    {
        0x2Eu,
        UDS_WriteDataByIdentifier
    },

    /*request download data */
    {
        0x34u,
        UDS_RequestDownload
    },

    /*transter data*/
    {
        0x36u,
        UDS_TransferData
    },

    /*request exit transfer data*/
    {
        0x37u,
        UDS_RequestTransferExit
    },

    /*routine control*/
    {
        0x31u,
        UDS_RoutineControl
    },

    /*reset ECU*/
    {
        0x11u,
        UDS_ResetECU
    },

    // /*diagnose mode control*/
    // {
    //     0x3Eu,
    //     UDS_TesterPresent
    // }
};

/*dig session*/
static void UDS_DigSession(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg)
{
    if(udsTxInfor.at(CurrStep).toObject().value("address").toString().compare("Physical") == 0)
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxPhyMsgID();
    }
    else
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxFunMsgID();
    }
    m_pstPDUMsg->aDataBuf[0] = udsTxInfor.at(CurrStep).toObject().value("id").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[1] = udsTxInfor.at(CurrStep).toObject().value("funcId").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->xDataLen = 0x02;
    if((m_pstPDUMsg->aDataBuf[1] & 0x80) == 0)
    {
        m_pstPDUMsg->exDataLen = 2;
        for(uint8_t idx = 0; idx < m_pstPDUMsg->exDataLen; idx++)
        {
            m_pstPDUMsg->exDataBuf[idx] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("rxData").toArray().at(idx).toString().toUShort(nullptr, 16);
        }
    }
    else
    {
        m_pstPDUMsg->exDataLen = 0;
    }

    UdsTp::DriverSetTxDataInTP(m_pstPDUMsg->xUdsId, m_pstPDUMsg->xDataLen, m_pstPDUMsg->aDataBuf, m_pstPDUMsg->exDataBuf);
}

/*control DTC setting*/
static void UDS_ControlDTCSetting(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg)
{
    if(udsTxInfor.at(CurrStep).toObject().value("address").toString().compare("Physical") == 0)
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxPhyMsgID();
    }
    else
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxFunMsgID();
    }
    m_pstPDUMsg->aDataBuf[0] = udsTxInfor.at(CurrStep).toObject().value("id").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[1] = udsTxInfor.at(CurrStep).toObject().value("funcId").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->xDataLen = 0x02;
    if((m_pstPDUMsg->aDataBuf[1] & 0x80) == 0)
    {
        m_pstPDUMsg->exDataLen = 2;
        for(uint8_t idx = 0; idx < m_pstPDUMsg->exDataLen; idx++)
        {
            m_pstPDUMsg->exDataBuf[idx] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("rxData").toArray().at(idx).toString().toUShort(nullptr, 16);
        }
    }
    else
    {
        m_pstPDUMsg->exDataLen = 0;
    }

    UdsTp::DriverSetTxDataInTP(m_pstPDUMsg->xUdsId, m_pstPDUMsg->xDataLen, m_pstPDUMsg->aDataBuf, m_pstPDUMsg->exDataBuf);
}

/*communication control*/
static void UDS_CommunicationControl(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg)
{
    if(udsTxInfor.at(CurrStep).toObject().value("address").toString().compare("Physical") == 0)
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxPhyMsgID();
    }
    else
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxFunMsgID();
    }
    m_pstPDUMsg->aDataBuf[0] = udsTxInfor.at(CurrStep).toObject().value("id").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[1] = udsTxInfor.at(CurrStep).toObject().value("funcId").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[2] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("commType").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->xDataLen = 0x03;
    if((m_pstPDUMsg->aDataBuf[1] & 0x80) == 0)
    {
        m_pstPDUMsg->exDataLen = 2;
        for(uint8_t idx = 0; idx < m_pstPDUMsg->exDataLen; idx++)
        {
            m_pstPDUMsg->exDataBuf[idx] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("rxData").toArray().at(idx).toString().toUShort(nullptr, 16);
        }
    }
    else
    {
        m_pstPDUMsg->exDataLen = 0;
    }

    UdsTp::DriverSetTxDataInTP(m_pstPDUMsg->xUdsId, m_pstPDUMsg->xDataLen, m_pstPDUMsg->aDataBuf, m_pstPDUMsg->exDataBuf);
}

/*security access*/
static void UDS_SecurityAccess(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg)
{
    uint8_t seedLen = 0;
    uint8_t seedArray[16] = {0};
    if(udsTxInfor.at(CurrStep).toObject().value("address").toString().compare("Physical") == 0)
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxPhyMsgID();
    }
    else
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxFunMsgID();
    }
    m_pstPDUMsg->aDataBuf[0] = udsTxInfor.at(CurrStep).toObject().value("id").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[1] = udsTxInfor.at(CurrStep).toObject().value("funcId").toString().toUShort(nullptr, 16);
    if(udsTxInfor.at(CurrStep).toObject().value("funcName").toString().compare("RequestSeed") == 0)
    {
        m_pstPDUMsg->xDataLen = 0x02;
    }
    else if(udsTxInfor.at(CurrStep).toObject().value("funcName").toString().compare("SendKey") == 0)
    {
        seedLen = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("KeyLen").toString().toUShort(nullptr, 16);
        for(uint8_t idx = 0; idx < seedLen; idx++)
        {
            seedArray[idx] = m_pstPDUMsg->aDataBuf[2 + idx];
        }
        if(udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("ProName").toString().compare("D587_PSS") == 0)
        {
            SecurityAlgorithm Securityer;
            Securityer.D587PSS(seedArray, &m_pstPDUMsg->aDataBuf[2]);
        }
        m_pstPDUMsg->xDataLen = 0x02 + seedLen;
    }
    if((m_pstPDUMsg->aDataBuf[1] & 0x80) == 0)
    {
        m_pstPDUMsg->exDataLen = 2;
        for(uint8_t idx = 0; idx < m_pstPDUMsg->exDataLen; idx++)
        {
            m_pstPDUMsg->exDataBuf[idx] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("rxData").toArray().at(idx).toString().toUShort(nullptr, 16);
        }
    }
    else
    {
        m_pstPDUMsg->exDataLen = 0;
    }

    UdsTp::DriverSetTxDataInTP(m_pstPDUMsg->xUdsId, m_pstPDUMsg->xDataLen, m_pstPDUMsg->aDataBuf, m_pstPDUMsg->exDataBuf);
}

/*read data by identifier*/
static void UDS_ReadDataByIdentifier(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg)
{
    if(udsTxInfor.at(CurrStep).toObject().value("address").toString().compare("Physical") == 0)
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxPhyMsgID();
    }
    else
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxFunMsgID();
    }
    m_pstPDUMsg->aDataBuf[0] = udsTxInfor.at(CurrStep).toObject().value("id").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[1] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("id").toArray().at(0).toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[2] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("id").toArray().at(1).toString().toUShort(nullptr, 16);
    m_pstPDUMsg->xDataLen = 0x03;
    m_pstPDUMsg->exDataLen = 3;
    for(uint8_t idx = 0; idx < m_pstPDUMsg->exDataLen; idx++)
    {
        m_pstPDUMsg->exDataBuf[idx] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("rxData").toArray().at(idx).toString().toUShort(nullptr, 16);
    }

    UdsTp::DriverSetTxDataInTP(m_pstPDUMsg->xUdsId, m_pstPDUMsg->xDataLen, m_pstPDUMsg->aDataBuf, m_pstPDUMsg->exDataBuf);
}

/*write data by identifier*/
static void UDS_WriteDataByIdentifier(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg)
{
    uint8_t length = 0;
    QDate currentDate = QDate::currentDate();
    if(udsTxInfor.at(CurrStep).toObject().value("address").toString().compare("Physical") == 0)
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxPhyMsgID();
    }
    else
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxFunMsgID();
    }
    m_pstPDUMsg->aDataBuf[0] = udsTxInfor.at(CurrStep).toObject().value("id").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[1] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("id").toArray().at(0).toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[2] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("id").toArray().at(1).toString().toUShort(nullptr, 16);
    length = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("inforLen").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->xDataLen = 0x03 + length;
    m_pstPDUMsg->aDataBuf[3] = currentDate.year() % 100;
    m_pstPDUMsg->aDataBuf[4] = currentDate.month();
    m_pstPDUMsg->aDataBuf[5] = currentDate.day();
    for(uint8_t idx = 6; idx < m_pstPDUMsg->xDataLen; idx++)
    {
        m_pstPDUMsg->aDataBuf[idx] = 0x30 + QRandomGenerator::global()->bounded(0, 10);
    }
    m_pstPDUMsg->exDataLen = 3;
    for(uint8_t idx = 0; idx < m_pstPDUMsg->exDataLen; idx++)
    {
        m_pstPDUMsg->exDataBuf[idx] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("rxData").toArray().at(idx).toString().toUShort(nullptr, 16);
    }

    UdsTp::DriverSetTxDataInTP(m_pstPDUMsg->xUdsId, m_pstPDUMsg->xDataLen, m_pstPDUMsg->aDataBuf, m_pstPDUMsg->exDataBuf);
}

/*request download*/
static void UDS_RequestDownload(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg)
{
    HexParser hexParser;
    CrcCalculater CrcCalculator;
    if(udsTxInfor.at(CurrStep).toObject().value("address").toString().compare("Physical") == 0)
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxPhyMsgID();
    }
    else
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxFunMsgID();
    }
    m_pstPDUMsg->aDataBuf[0] = udsTxInfor.at(CurrStep).toObject().value("id").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[1] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("dataFormat").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[2] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("addressAndLengthFormat").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->xDataLen = 0x03 + (m_pstPDUMsg->aDataBuf[2] >> 4) + (m_pstPDUMsg->aDataBuf[2] & 0x0F);
    ActionFlow.caclCrc = 0;
    if(udsTxInfor.at(CurrStep).toObject().value("funcName").toString().compare("RequestDownloadFlashDriver") == 0)
    {
        // 获取当前目录
        QDir currentDir = QDir::current();
        if(currentDir.cd("../../SoftFile"))
        {
            // qDebug()<<currentDir.absolutePath();
            hexParser.ParseHex(currentDir.absolutePath() + "/flash_api.hex", &ActionFlow.rqstAddr, &ActionFlow.rqstSize, ActionFlow.transData);
        }
        for(uint8_t idx = 0; idx < (m_pstPDUMsg->aDataBuf[2] >> 4); idx++)
        {
            m_pstPDUMsg->aDataBuf[3 + idx] = ActionFlow.rqstAddr >> ((m_pstPDUMsg->aDataBuf[2] >> 4) - 1 - idx) * 8;
        }
        for(uint8_t idx = 0; idx < (m_pstPDUMsg->aDataBuf[2] & 0x0F); idx++)
        {
            m_pstPDUMsg->aDataBuf[3 + (m_pstPDUMsg->aDataBuf[2] >> 4) + idx] = ActionFlow.rqstSize >> ((m_pstPDUMsg->aDataBuf[2] & 0x0F) - 1 - idx) * 8;
        }
        CrcCalculator.CRC_CreatCRC16_CITT(ActionFlow.transData, ActionFlow.rqstSize, (uint16_t *)&ActionFlow.caclCrc);
    }
    else
    {
        for(uint8_t idx = 0; idx < (m_pstPDUMsg->aDataBuf[2] >> 4); idx++)
        {
            m_pstPDUMsg->aDataBuf[3 + idx] = ActionFlow.rqstAddr >> ((m_pstPDUMsg->aDataBuf[2] >> 4) - 1 - idx) * 8;
        }
        for(uint8_t idx = 0; idx < (m_pstPDUMsg->aDataBuf[2] & 0x0F); idx++)
        {
            m_pstPDUMsg->aDataBuf[3 + (m_pstPDUMsg->aDataBuf[2] >> 4) + idx] = ActionFlow.rqstSize >> ((m_pstPDUMsg->aDataBuf[2] & 0x0F) - 1 - idx) * 8;
        }
    }
    m_pstPDUMsg->exDataLen = 1;
    for(uint8_t idx = 0; idx < m_pstPDUMsg->exDataLen; idx++)
    {
        m_pstPDUMsg->exDataBuf[idx] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("rxData").toArray().at(idx).toString().toUShort(nullptr, 16);
    }

    UdsTp::DriverSetTxDataInTP(m_pstPDUMsg->xUdsId, m_pstPDUMsg->xDataLen, m_pstPDUMsg->aDataBuf, m_pstPDUMsg->exDataBuf);
}

/*transfer data*/
static void UDS_TransferData(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg)
{
    uint32_t tranBytes = 0;
    if(udsTxInfor.at(CurrStep).toObject().value("address").toString().compare("Physical") == 0)
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxPhyMsgID();
    }
    else
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxFunMsgID();
    }
    m_pstPDUMsg->aDataBuf[0] = udsTxInfor.at(CurrStep).toObject().value("id").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[1] = ActionFlow.blockIdx;
    if(ActionFlow.rqstSize - ActionFlow.dataIdx < ActionFlow.tranSize)
    {
        tranBytes = ActionFlow.rqstSize - ActionFlow.dataIdx;
    }
    else
    {
        tranBytes = ActionFlow.tranSize;
    }
    for(uint32_t idx = 0; idx < tranBytes; idx++)
    {
        m_pstPDUMsg->aDataBuf[2 + idx] = ActionFlow.transData[ActionFlow.dataIdx + idx];
    }
    ActionFlow.dataIdx += tranBytes;
    m_pstPDUMsg->xDataLen = tranBytes + 2;

    m_pstPDUMsg->exDataLen = 1;
    for(uint8_t idx = 0; idx < m_pstPDUMsg->exDataLen; idx++)
    {
        m_pstPDUMsg->exDataBuf[idx] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("rxData").toArray().at(idx).toString().toUShort(nullptr, 16);
    }

    ActionFlow.blockIdx++;

    UdsTp::DriverSetTxDataInTP(m_pstPDUMsg->xUdsId, m_pstPDUMsg->xDataLen, m_pstPDUMsg->aDataBuf, m_pstPDUMsg->exDataBuf);
}

/*request transfer exit*/
static void UDS_RequestTransferExit(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg)
{
    if(udsTxInfor.at(CurrStep).toObject().value("address").toString().compare("Physical") == 0)
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxPhyMsgID();
    }
    else
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxFunMsgID();
    }
    m_pstPDUMsg->aDataBuf[0] = udsTxInfor.at(CurrStep).toObject().value("id").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->xDataLen = 1;

    m_pstPDUMsg->exDataLen = 1;
    for(uint8_t idx = 0; idx < m_pstPDUMsg->exDataLen; idx++)
    {
        m_pstPDUMsg->exDataBuf[idx] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("rxData").toArray().at(idx).toString().toUShort(nullptr, 16);
    }

    UdsTp::DriverSetTxDataInTP(m_pstPDUMsg->xUdsId, m_pstPDUMsg->xDataLen, m_pstPDUMsg->aDataBuf, m_pstPDUMsg->exDataBuf);
}

/*routine control*/
static void UDS_RoutineControl(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg)
{
    HexParser hexParser;
    if(udsTxInfor.at(CurrStep).toObject().value("address").toString().compare("Physical") == 0)
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxPhyMsgID();
    }
    else
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxFunMsgID();
    }
    m_pstPDUMsg->aDataBuf[0] = udsTxInfor.at(CurrStep).toObject().value("id").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[1] = udsTxInfor.at(CurrStep).toObject().value("funcId").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[2] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("id").toArray().at(0).toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[3] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("id").toArray().at(1).toString().toUShort(nullptr, 16);
    m_pstPDUMsg->xDataLen = 0x04;
    if(udsTxInfor.at(CurrStep).toObject().value("funcName").toString().compare("CheckProgrammingPrecondition") == 0)
    {

    }
    else if(udsTxInfor.at(CurrStep).toObject().value("funcName").toString().compare("ActiveFlashProgramming") == 0)
    {
        for(uint8_t idx = 0; idx < sizeof(ActionFlow.rqstAddr); idx++)
        {
            m_pstPDUMsg->aDataBuf[4 + idx] = ActionFlow.rqstAddr >> (sizeof(ActionFlow.rqstAddr) - 1 - idx) * 8;
        }
        m_pstPDUMsg->xDataLen += sizeof(ActionFlow.rqstAddr);
    }
    else if(udsTxInfor.at(CurrStep).toObject().value("funcName").toString().compare("StartEraseFlash") == 0)
    {
        hexParser.ParseHex(FlashExecutor::getAppPath(), &ActionFlow.rqstAddr, &ActionFlow.rqstSize, ActionFlow.transData);
        for(uint8_t idx = 0; idx < sizeof(ActionFlow.rqstAddr); idx++)
        {
            m_pstPDUMsg->aDataBuf[4 + idx] = ActionFlow.rqstAddr >> (sizeof(ActionFlow.rqstAddr) - 1 - idx) * 8;
        }
        m_pstPDUMsg->xDataLen += sizeof(ActionFlow.rqstAddr);
        for(uint8_t idx = 0; idx < sizeof(ActionFlow.rqstSize); idx++)
        {
            m_pstPDUMsg->aDataBuf[4 + idx + sizeof(ActionFlow.rqstAddr)] = ActionFlow.rqstSize >> (sizeof(ActionFlow.rqstSize) - 1 - idx) * 8;
        }
        m_pstPDUMsg->xDataLen += sizeof(ActionFlow.rqstSize);
    }
    else if(udsTxInfor.at(CurrStep).toObject().value("funcName").toString().compare("CheckValidApplication") == 0)
    {

    }
    if((m_pstPDUMsg->aDataBuf[1] & 0x80) == 0)
    {
        m_pstPDUMsg->exDataLen = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("rxData").toArray().count();
        for(uint8_t idx = 0; idx < m_pstPDUMsg->exDataLen; idx++)
        {
            m_pstPDUMsg->exDataBuf[idx] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("rxData").toArray().at(idx).toString().toUShort(nullptr, 16);
        }
    }
    else
    {
        m_pstPDUMsg->exDataLen = 0;
    }

    UdsTp::DriverSetTxDataInTP(m_pstPDUMsg->xUdsId, m_pstPDUMsg->xDataLen, m_pstPDUMsg->aDataBuf, m_pstPDUMsg->exDataBuf);
}

/*reset ECU*/
static void UDS_ResetECU(uint8_t CurrStep, QJsonArray udsTxInfor, tUdsAppMsgInfo *m_pstPDUMsg)
{
    if(udsTxInfor.at(CurrStep).toObject().value("address").toString().compare("Physical") == 0)
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxPhyMsgID();
    }
    else
    {
        m_pstPDUMsg->xUdsId = UdsTp::GetConfigTxFunMsgID();
    }
    m_pstPDUMsg->aDataBuf[0] = udsTxInfor.at(CurrStep).toObject().value("id").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->aDataBuf[1] = udsTxInfor.at(CurrStep).toObject().value("funcId").toString().toUShort(nullptr, 16);
    m_pstPDUMsg->xDataLen = 0x02;
    if((m_pstPDUMsg->aDataBuf[1] & 0x80) == 0)
    {
        m_pstPDUMsg->exDataLen = 2;
        for(uint8_t idx = 0; idx < m_pstPDUMsg->exDataLen; idx++)
        {
            m_pstPDUMsg->exDataBuf[idx] = udsTxInfor.at(CurrStep).toObject().value("other").toObject().value("rxData").toArray().at(idx).toString().toUShort(nullptr, 16);
        }
    }
    else
    {
        m_pstPDUMsg->exDataLen = 0;
    }

    UdsTp::DriverSetTxDataInTP(m_pstPDUMsg->xUdsId, m_pstPDUMsg->xDataLen, m_pstPDUMsg->aDataBuf, m_pstPDUMsg->exDataBuf);
}

// /*Tester present service*/
// static void UDS_TesterPresent(QJsonArray udsTxInfor)
// {

// }

/* get uds service config information */
tUDSService* UdsClient::UDS_GetUDSServiceInfo(uint8_t *m_pSupServItem)
{
    *m_pSupServItem = sizeof(gs_astUDSService) / sizeof(gs_astUDSService[0u]);

    return (tUDSService*) &gs_astUDSService[0u];
}
